/*
 * SongListTablePanel.java
 *
 * Created on June 20, 2005, 8:27 PM
 */
package com.bff.mpd.musicjukebox.ui;

import com.bff.bjj.ui.component.BJJButton;
import com.bff.mpd.musicjukebox.lib.AlbumTableModel;
import com.bff.mpd.musicjukebox.lib.AllAlbum;
import com.bff.mpd.musicjukebox.lib.ArtistTableModel;
import com.bff.mpd.musicjukebox.lib.ColorProperties;
import com.bff.mpd.musicjukebox.lib.JukeboxProperties;
import com.bff.mpd.musicjukebox.lib.SearchTableModel;
import com.bff.mpd.musicjukebox.ui.components.HideTableColumnListener;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumn;
import com.bff.mpd.musicjukebox.lib.SongTableModel;
import com.bff.mpd.musicjukebox.ui.components.LengthCellRenderer;
import com.bff.bjj.ui.component.BJJPanel;
import com.bff.mpd.musicjukebox.ui.components.SongCellRenderer;
import com.bff.mpd.musicjukebox.ui.components.SongScrollPane;
import com.bff.mpd.musicjukebox.ui.components.SongTable;
import com.bff.mpd.musicjukebox.ui.components.SonglistPopupMenu;
import com.bff.mpd.utils.TableSorter;
import com.bff.mpd.utils.Utils;
import java.util.ArrayList;
import java.util.List;
import javax.swing.DefaultComboBoxModel;
import javax.swing.ScrollPaneConstants;
import org.bff.javampd.MPDDatabase;
import org.bff.javampd.MPDPlaylist;
import org.bff.javampd.exception.MPDConnectionException;
import org.bff.javampd.exception.MPDPlaylistException;
import org.bff.javampd.objects.MPDAlbum;
import org.bff.javampd.objects.MPDArtist;
import org.bff.javampd.objects.MPDGenre;
import org.bff.javampd.objects.MPDSong;

/**
 *
 * @author  Bill
 */
public class SongListTablePanel
        extends BJJPanel
        implements ComponentListener {

    private SongTableModel tableModel;
    private MPDPlaylist playlist;
    private MPDDatabase database;
    private TableSorter tableSorter;
    private MPDAlbum album;
    private MPDArtist artist;
    private MPDGenre genre;
    private String year;
    private DefaultComboBoxModel groupByModel;
    private JukeboxProperties jp;

    /** Creates new form SongListTablePanel */
    public SongListTablePanel() {
        super();
        jp = JukeboxProperties.getInstance();
        setPlaylist(jp.getPlaylist());
        setDatabase(jp.getDatabase());
        initComponents();
        setScrollbarSize();
        MouseListener playlistPopupListener = new PlaylistPopupListener();
        infoTable.addMouseListener(playlistPopupListener);
        addComponentListener(this);
        setColors();
        infoTableScrollPane.getViewport().setBackground(ColorProperties.LIST_BACKGROUND_EVEN);
        loadProgressBar.setVisible(false);

        panelGroupByFolder.setVisible(false);        
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        btnPanel = new BJJPanel();
        jPanel1 = new BJJPanel();
        btnAddToPlaylist = new BJJButton();
        lblActions = new javax.swing.JLabel();
        jPanel2 = new BJJPanel();
        infoTableScrollPane = new SongScrollPane();
        infoTable = new SongTable();
        getScrollPane().setTable(infoTable);
        jPanel3 = new BJJPanel();
        loadProgressBar = new javax.swing.JProgressBar();
        panelGroupByFolder = new BJJPanel();
        jLabel1 = new javax.swing.JLabel();
        cbGroupBy = new javax.swing.JComboBox();

        setLayout(new java.awt.BorderLayout());

        btnPanel.setLayout(new java.awt.BorderLayout());

        btnAddToPlaylist.setText("Add to Playlist");
        btnAddToPlaylist.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAddToPlaylistActionPerformed(evt);
            }
        });
        jPanel1.add(btnAddToPlaylist);

        btnPanel.add(jPanel1, java.awt.BorderLayout.SOUTH);

        lblActions.setForeground(new java.awt.Color(255, 0, 102));
        lblActions.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        lblActions.setText(" ");
        btnPanel.add(lblActions, java.awt.BorderLayout.CENTER);

        add(btnPanel, java.awt.BorderLayout.SOUTH);

        jPanel2.setLayout(new java.awt.BorderLayout());

        infoTableScrollPane.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        infoTableScrollPane.setMaximumSize(new java.awt.Dimension(800, 32767));
        infoTableScrollPane.setPreferredSize(new java.awt.Dimension(200, 200));

        infoTable.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        infoTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_OFF);
        infoTable.setOpaque(false);
        infoTable.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                infoTableMouseClicked(evt);
            }
            public void mousePressed(java.awt.event.MouseEvent evt) {
                infoTableMousePressed(evt);
            }
        });
        infoTableScrollPane.setViewportView(infoTable);

        jPanel2.add(infoTableScrollPane, java.awt.BorderLayout.CENTER);

        jPanel3.setLayout(new java.awt.BorderLayout());

        loadProgressBar.setIndeterminate(true);
        loadProgressBar.setString("Loading Songs");
        loadProgressBar.setStringPainted(true);
        jPanel3.add(loadProgressBar, java.awt.BorderLayout.SOUTH);

        jLabel1.setText("Multiple albums exist");
        panelGroupByFolder.add(jLabel1);

        cbGroupBy.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
        cbGroupBy.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                cbGroupByItemStateChanged(evt);
            }
        });
        panelGroupByFolder.add(cbGroupBy);

        jPanel3.add(panelGroupByFolder, java.awt.BorderLayout.CENTER);

        jPanel2.add(jPanel3, java.awt.BorderLayout.SOUTH);

        add(jPanel2, java.awt.BorderLayout.CENTER);
    }// </editor-fold>//GEN-END:initComponents

    private void infoTableMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_infoTableMousePressed
        if (SwingUtilities.isRightMouseButton(evt)) {
            int row = infoTable.rowAtPoint(evt.getPoint());
            MPDSong song = tableModel.getSong(tableSorter.modelIndex(row));
            SonglistPopupMenu popupMenu = new SonglistPopupMenu(Utils.getParentComponent(this), getPlaylist(), song);
            if (evt.isPopupTrigger()) {
                popupMenu.show(evt.getComponent(),
                        evt.getX(), evt.getY());
            }
        }
    }//GEN-LAST:event_infoTableMousePressed

    private void infoTableMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_infoTableMouseClicked
        if (evt.getClickCount() == 2) {
            int row = infoTable.rowAtPoint(evt.getPoint());
            MPDSong song = tableModel.getSong(tableSorter.modelIndex(row));
            this.setCursor(Utils.getHourglassCursor());
            try {
                getPlaylist().addSong(song);
            } catch (MPDConnectionException ex) {
                Logger.getLogger(SongListTablePanel.class.getName()).log(Level.SEVERE, null, ex);
            } catch (MPDPlaylistException ex) {
                Logger.getLogger(SongListTablePanel.class.getName()).log(Level.SEVERE, null, ex);
            }
            lblActions.setText(song.getTitle() + " inserted into the playlist.");
            this.setCursor(Utils.getNormalCursor());
        }
    }//GEN-LAST:event_infoTableMouseClicked

    private void btnAddToPlaylistActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAddToPlaylistActionPerformed
        this.setCursor(Utils.getHourglassCursor());
        try {
            int rows[] = infoTable.getSelectedRows();

            if (rows.length > 1) {
                List<MPDSong> list = new ArrayList<MPDSong>();
                for (int i = 0; i < rows.length; i++) {
                    MPDSong song = tableModel.getSong(tableSorter.modelIndex(rows[i]));
                    list.add(song);
                }
                getPlaylist().addSongs(list);

                lblActions.setText(rows.length + " songs inserted into the playlist.");
            } else {
                MPDSong song = tableModel.getSong(tableSorter.modelIndex(rows[0]));
                getPlaylist().addSong(song);
                lblActions.setText(song.getTitle() + " inserted into the playlist.");
            }
        } catch (MPDConnectionException ex) {
            Logger.getLogger(SongListTablePanel.class.getName()).log(Level.SEVERE, null, ex);
        } catch (MPDPlaylistException ex) {
            Logger.getLogger(SongListTablePanel.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            this.setCursor(Utils.getNormalCursor());
        }
    }//GEN-LAST:event_btnAddToPlaylistActionPerformed

    private void cbGroupByItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cbGroupByItemStateChanged
        if (tableModel instanceof AlbumTableModel) {
            ((AlbumTableModel) tableModel).filterGroup((String) groupByModel.getSelectedItem());
        }
    }//GEN-LAST:event_cbGroupByItemStateChanged

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnAddToPlaylist;
    private javax.swing.JPanel btnPanel;
    private javax.swing.JComboBox cbGroupBy;
    private javax.swing.JTable infoTable;
    private javax.swing.JScrollPane infoTableScrollPane;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JLabel lblActions;
    private javax.swing.JProgressBar loadProgressBar;
    private javax.swing.JPanel panelGroupByFolder;
    // End of variables declaration//GEN-END:variables

    public SongScrollPane getScrollPane() {
        return (SongScrollPane) infoTableScrollPane;
    }

    public void setYear(String year) {
        this.year = year;
    }

    void setAlbumSongs(MPDAlbum album) {
        setArtist(null);
        setAlbum(album);
        if (album != null) {
            setModel(new AlbumTableModel(album));
        }
    }

    public void setAlbumSongs(MPDArtist artist, MPDAlbum album) {
        setArtist(artist);
        setAlbum(album);
        if (artist != null && album != null) {
            if (album instanceof AllAlbum) {
                setModel(new ArtistTableModel(artist));
            } else {
                setModel(new AlbumTableModel(artist, album));
            }
        }
    }

    public void setGenreSongs(MPDGenre genre, MPDAlbum album) {
        setGenre(genre);
        setAlbum(album);
        if (genre != null && album != null) {
            setModel(new AlbumTableModel(genre, album));
        }
    }

    public void setYearSongs(String year, MPDAlbum album) {
        setYear(year);
        setAlbum(album);
        if (year != null && album != null) {
            setModel(new AlbumTableModel(year, album));
        }
    }

    public void setArtistSongs(MPDArtist artist) {
        setArtist(artist);
        setAlbum(null);
        if (artist != null) {
            setModel(new ArtistTableModel(artist));
        }
    }

    public void setGenreSongs(MPDGenre genre) {
        setGenre(genre);
        setAlbum(null);
        if (genre != null) {
            setModel(new ArtistTableModel(genre));

        }
    }

    public void setYearSongs(String year) {
        setYear(year);
        setAlbum(null);
        if (year != null && album != null) {
            setModel(new ArtistTableModel(year));
        }
    }

    public MPDAlbum getAlbum() {
        return this.album;
    }

    public void setModel(SongTableModel tableModel) {
        this.tableModel = tableModel;

        JTableHeader tableHeader = infoTable.getTableHeader();
        tableHeader.setFont(new Font(tableHeader.getFont().getFontName(), Font.BOLD, tableHeader.getFont().getSize()));
        tableSorter = new TableSorter(tableModel);
        tableSorter.setSortingStatus(tableModel.getSortColumn(), TableSorter.ASCENDING);
        tableSorter.setTableModel(tableModel);
        tableSorter.setTableHeader(infoTable.getTableHeader());

        infoTable.setModel(tableSorter);
        new HideTableColumnListener(infoTable);
        //infoTable.addMouseListener(new HideTableColumnListener())

        if ((tableModel instanceof AlbumTableModel) && jp.isGroupByFolder()) {
            AlbumTableModel model = (AlbumTableModel) tableModel;
            if (model.getGroupList().size() > 1) {
                panelGroupByFolder.setVisible(true);
                groupByModel = new DefaultComboBoxModel();
                for (String s : model.getGroupList()) {
                    groupByModel.addElement(s);
                    cbGroupBy.setModel(groupByModel);
                    model.filterGroup((String) groupByModel.getSelectedItem());
                }
            } else {
                panelGroupByFolder.setVisible(false);
            }

        } else {
            panelGroupByFolder.setVisible(false);
        }
        int width = 0;

        TableColumn tc = infoTable.getColumnModel().getColumn(tableModel.getLengthColumnIndex());
        tc.setCellRenderer(new LengthCellRenderer());
        width +=
                tc.getWidth();

        if (tableModel.getAlbumColumnIndex() > -1) {
            tc = infoTable.getColumnModel().getColumn(tableModel.getAlbumColumnIndex());
            tc.setCellRenderer(new SongCellRenderer());
        }

        if (tableModel.getArtistColumnIndex() > -1) {
            tc = infoTable.getColumnModel().getColumn(tableModel.getArtistColumnIndex());
            tc.setCellRenderer(new SongCellRenderer());
        }

        if (tableModel.getTitleColumnIndex() > -1) {
            tc = infoTable.getColumnModel().getColumn(tableModel.getTitleColumnIndex());
            tc.setCellRenderer(new SongCellRenderer());
        }

        if (tableModel.getGenreColumnIndex() > -1) {
            tc = infoTable.getColumnModel().getColumn(tableModel.getGenreColumnIndex());
            tc.setCellRenderer(new SongCellRenderer());
            width += tc.getWidth();
        }

        if (tableModel.getTrackColumnIndex() > -1) {
            tc = infoTable.getColumnModel().getColumn(tableModel.getTrackColumnIndex());
            tc.setCellRenderer(new CenterCellRenderer());
            width += tc.getWidth();
        }

        if (tableModel.getYearColumnIndex() > -1) {
            tc = infoTable.getColumnModel().getColumn(tableModel.getYearColumnIndex());
            tc.setCellRenderer(new CenterCellRenderer());
            width += tc.getWidth();
        }

        setTableSize();
        Utils.autoResizeTable(infoTable, true, 25);
        setTableSize();

    }

    private void setTableSize() {
        infoTable.setPreferredSize(new Dimension(this.getWidth() - 0, (int) infoTable.getRowHeight() * infoTable.getRowCount()));
    }

    void setProgressBarVisible(boolean visible) {
        if (loadProgressBar != null) {
            loadProgressBar.setVisible(visible);
        }
    }

    /**
     * @return the database
     */
    public MPDDatabase getDatabase() {
        return database;
    }

    /**
     * @param database the database to set
     */
    public void setDatabase(MPDDatabase database) {
        this.database = database;
    }

    /**
     * @return the playlist
     */
    public MPDPlaylist getPlaylist() {
        return playlist;
    }

    /**
     * @param playlist the playlist to set
     */
    public void setPlaylist(MPDPlaylist playlist) {
        this.playlist = playlist;
    }

    /**
     * @param album the album to set
     */
    public void setAlbum(MPDAlbum album) {
        this.album = album;
    }

    /**
     * @return the artist
     */
    public MPDArtist getArtist() {
        return artist;
    }

    /**
     * @param artist the artist to set
     */
    public void setArtist(MPDArtist artist) {
        this.artist = artist;
    }

    /**
     * @return the genre
     */
    public MPDGenre getGenre() {
        return genre;
    }

    /**
     * @param genre the genre to set
     */
    public void setGenre(MPDGenre genre) {
        this.genre = genre;
    }

    /**
     * @return the year
     */
    public String getYear() {
        return year;
    }

    void setSongs(List<MPDSong> songList) {
        setModel(new SearchTableModel(songList));
    }

    void setSong(MPDSong song) {
        List<MPDSong> songs = new ArrayList<MPDSong>();
        songs.add(song);
        setModel(new SearchTableModel(songs));
    }

    private class CenterCellRenderer extends SongCellRenderer {

        CenterCellRenderer() {
            setHorizontalAlignment(SwingConstants.CENTER);
        }
    }

    private void setScrollbarSize() {
        int width = infoTable.getWidth() + 2;
        int height = jPanel2.getHeight() - 5;
        int maxWidth = jPanel2.getWidth() - 5;

        if (infoTable.getHeight() > height && width < maxWidth) {
            width += 18;
        }

        if (width > maxWidth) {
            width = maxWidth;
        }

        infoTableScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        infoTableScrollPane.setPreferredSize(new Dimension(width, height));
        infoTableScrollPane.setSize(new Dimension(width, height));
    }

    class PlaylistPopupListener extends MouseAdapter {

        @Override
        public void mousePressed(MouseEvent evt) {
            if (SwingUtilities.isRightMouseButton(evt)) {
                maybeShowPopup(evt);
            }
        }

        @Override
        public void mouseReleased(MouseEvent evt) {
            maybeShowPopup(evt);
        }

        private void maybeShowPopup(MouseEvent evt) {
            int row = infoTable.rowAtPoint(evt.getPoint());
            MPDSong song = tableModel.getSong(tableSorter.modelIndex(row));
            SonglistPopupMenu popupMenu = new SonglistPopupMenu(Utils.getParentComponent(evt.getComponent()), getPlaylist(), song);
            if (evt.isPopupTrigger()) {
                popupMenu.show(evt.getComponent(),
                        evt.getX(), evt.getY());
            }
        }
    }

    @Override
    public void componentHidden(ComponentEvent arg0) {
        //dont care
    }

    @Override
    public void componentMoved(ComponentEvent arg0) {
        //dont care
    }

    @Override
    public void componentResized(ComponentEvent arg0) {
        setTableSize();
    }

    @Override
    public void componentShown(ComponentEvent arg0) {
        //dont care
    }
}
